/*  static char SccsId[] = "@(#)asl.h	1.16   3/25/96";
 *
 *         Copyright (c) KUBOTA Corporation and HUDSON SOFT,
 *                  1994, 1995 All Rights Reserved
 *
 *  This software comprises unpublished confidential information of
 *  KUBOTA Corp. and HUDSON SOFT. It may not be used, copied or made
 *  available to anyone, except in accordance with the license under
 *  which it is furnished.
 */

#ifndef _ASL_H_
#define _ASL_H_

#if defined( _ASLLIB_ )
#pragma	defseg(-C,asl_code)
#pragma	defseg(-D,asl_data)
#pragma	defseg(-Z,asl_zero)
#pragma	defseg(-B,asl_bss)
#pragma	seg(asl_code)
#pragma	seg(asl_data)
#pragma	seg(asl_zero)
#pragma	seg(asl_bss)

#define	__ASL_FORCE_DRAW
#undef	__ASL_DEPEND_ON_FARL
#endif	/* _ASLLIB_ */

#if !defined( Bool )
#define	Bool	int
#endif
#if !defined( True )
#define	True	(1)
#endif
#if !defined( False )
#define	False	(0)
#endif


/***	ASL Address Offset (by Word).				***/
#define	ASL_ADR_HEAD		( 0)
#define	ASL_ADR_CNTL		( 1)
#define	ASL_ADR_DSP_X_POS	( 2)
#define	ASL_ADR_DSP_Y_POS	( 3)
#define	ASL_ADR_DSP_XY_SIZE	( 4)
#define	ASL_ADR_SRC_XY_POS	( 5)
#define	ASL_ADR_Z_VAL		( 6)
#define	ASL_ADR_SRC_XY_SIZE 	( 7)
#define ASL_ADR_SRC_X_OFF	( 8)
#define ASL_ADR_SRC_Y_OFF	( 9)
#define ASL_ADR_SRC_X_SCAN	(10)
#define ASL_ADR_SRC_Y_SCAN	(11)
#define	ASL_ADR_PT_BANK		(12)
#define	ASL_ADR_PT_OFFSET	(13)


/***	ASL Word 0.					***/

/*		Sprite Function Level.			*/
#define	ASL_MSK_FNC_LVL		(0xe000)
#define	ASL_SFT_FNC_LVL		(13)

#define	ASL_VAL_FNC_NONE	( 0 << ASL_SFT_FNC_LVL )
#define	ASL_VAL_FNC_NORM	( 1 << ASL_SFT_FNC_LVL )
#define	ASL_VAL_FNC_NORM_Z	( 2 << ASL_SFT_FNC_LVL )
#define	ASL_VAL_FNC_ZOOMROT	( 3 << ASL_SFT_FNC_LVL )
#define	ASL_VAL_FNC_TBL		( 4 << ASL_SFT_FNC_LVL )

/*		HV Flip Flag.				*/
#define	ASL_MSK_V_FLIP		(0x0200)
#define	ASL_SFT_V_FLIP		(9)
#define	ASL_VAL_V_FLIP		( ASL_MSK_V_FLIP )

#define	ASL_MSK_H_FLIP		(0x0100)
#define	ASL_SFT_H_FLIP		(8)
#define	ASL_VAL_H_FLIP		( ASL_MSK_H_FLIP )

#define	ASL_MSK_HV_FLIP		( ASL_MSK_V_FLIP | ASL_MSK_H_FLIP )
#define	ASL_SFT_HV_FLIP		( ASL_SFT_H_FLIP )

#define	ASL_VAL_HV_FLIP_NONE	(0)
#define	ASL_VAL_HV_FLIP_H	( ASL_VAL_H_FLIP )
#define	ASL_VAL_HV_FLIP_V	( ASL_VAL_V_FLIP )
#define	ASL_VAL_HV_FLIP_HV	( ASL_VAL_H_FLIP | ASL_VAL_V_FLIP )

/*		Sprite Source Bank Select.		*/
#define	ASL_MSK_BANKSEL		(0x001f)
#define	ASL_SFT_BANKSEL		(0)

#define	ASL_MSK_HEAD		( ASL_MSK_FNC_LVL | ASL_MSK_HV_FLIP \
							| ASL_MSK_BANKSEL )


/***	ASL Word 1.					***/

/*		Collision Detection Enable.		*/
#define	ASL_MSK_CDEN		(0x8000)
#define	ASL_SFT_CDEN		(15)
#define	ASL_VAL_CDEN		( ASL_MSK_CDEN )

/*		Pixel Draw Enable. (Ghost)		*/
#define	ASL_MSK_GHST		(0x4000)
#define	ASL_SFT_GHST		(14)
#define	ASL_VAL_GHST		( ASL_MSK_GHST )

/*		Z Compare Flag.				*/
#define	ASL_MSK_ZCMP		(0x2000)
#define	ASL_SFT_ZCMP		(13)
#define	ASL_VAL_ZCMP		( ASL_MSK_ZCMP )

/*		Z Write Enable.				*/
#define	ASL_MSK_ZWEN		(0x1000)
#define	ASL_SFT_ZWEN		(12)
#define	ASL_VAL_ZWEN		( ASL_MSK_ZWEN )

/*		CD Result Index.			*/
#define	ASL_MSK_CDRES_IDX	(0x0700)
#define	ASL_SFT_CDRES_IDX	(8)

/*		Flag Set Bits.				*/
#define	ASL_MSK_FLAG_SET	(0x00f0)
#define	ASL_SFT_FLAG_SET	(4)

/*		Flag Check Mask.			*/
#define	ASL_MSK_FLAG_CHK	(0x000f)
#define	ASL_SFT_FLAG_CHK	(0)

#define	ASL_MSK_CNTL		( ASL_MSK_CDEN | ASL_MSK_GHST | ASL_MSK_ZCMP \
					| ASL_MSK_ZWEN | ASL_MSK_CDRES_IDX \
					| ASL_MSK_FLAG_SET | ASL_MSK_FLAG_CHK )


/***	ASL Word 2. (Disp. X Pos)			***/
#define	ASL_MSK_DSP_X_POS	(0x03ff)
#define	ASL_SFT_DSP_X_POS	(0)

/***	ASL Word 3. (Disp. Y Pos)			***/
#define	ASL_MSK_DSP_Y_POS	(0x01ff)
#define	ASL_SFT_DSP_Y_POS	(0)

/***	ASL Word 4. (Disp. Y/X Size)			***/
#define	ASL_MSK_DSP_Y_SIZE	(0xff00)
#define	ASL_SFT_DSP_Y_SIZE	(8)

#define	ASL_MSK_DSP_X_SIZE	(0x00ff)
#define	ASL_SFT_DSP_X_SIZE	(0)

/***	ASL Word 5. (Src. Y/X Pos)			***/
#define	ASL_MSK_SRC_Y_POS	(0xff00)
#define	ASL_SFT_SRC_Y_POS	(8)

#define	ASL_MSK_SRC_X_POS	(0x00ff)
#define	ASL_SFT_SRC_X_POS	(0)

/***	ASL Word 6. (Z Value)				***/
#define	ASL_MSK_Z_VAL		(0xffff)
#define	ASL_SFT_Z_VAL		(0)

/***	ASL Word 7. (Src. Y/X Size)			***/
#define	ASL_MSK_SRC_Y_SIZE	(0xff00)
#define	ASL_SFT_SRC_Y_SIZE	(8)

#define	ASL_MSK_SRC_X_SIZE	(0x00ff)
#define	ASL_SFT_SRC_X_SIZE	(0)

/***	ASL Word 8. (Src. X Offset)			***/
#define	ASL_MSK_SRC_X_OFF	(0xffff)
#define	ASL_SFT_SRC_X_OFF	(0)

/***	ASL Word 9. (Src. Y Offset)			***/
#define	ASL_MSK_SRC_Y_OFF	(0xffff)
#define	ASL_SFT_SRC_Y_OFF	(0)

/***	ASL Word 10. (Src. X Scan)			***/
#define	ASL_MSK_SRC_X_SCAN	(0xffff)
#define	ASL_SFT_SRC_X_SCAN	(0)

/***	ASL Word 11. (Src. Y Scan)			***/
#define	ASL_MSK_SRC_Y_SCAN	(0xffff)
#define	ASL_SFT_SRC_Y_SCAN	(0)

/***	ASL Word 12. (Parameter Table Bank Select)	***/
#define	ASL_MSK_PT_BANKSEL	(0x001f)
#define	ASL_SFT_PT_BANKSEL	(0)

/***	ASL Word 12. (Parameter Table Offset Address)	***/
#define	ASL_MSK_PT_OFF_ADDR	(0xffff)
#define	ASL_SFT_PT_OFF_ADDR	(0)


typedef	struct {
	unsigned short	head;
	unsigned short	cntl;
	unsigned short	dsp_x_pos;
	unsigned short	dsp_y_pos;
	unsigned short	dsp_xy_size;
	unsigned short	src_xy_pos;
	unsigned short	z;
	unsigned short	src_xy_size;
	short		src_x_off;
	short		src_y_off;
	short		src_x_scan;
	short		src_y_scan;
	unsigned short	pt_bank_sel;
	unsigned short	pt_off_addr;
	unsigned short	reserved1;
	unsigned short	reserved2;
} ASLSct;

typedef	struct {
	short		x_off;
	short		y_off;
	short		x_scan;
	short		y_scan;
} ASLPt;

typedef	struct {
	short		bank;
	short		x_pos;
	short		y_pos;
	short		x_size;
	short		y_size;
	short		x_hot;
	short		y_hot;
} ASLSource;

typedef struct {
	short		dstXt;
	short		dstWt;
	short		dstXb;
	short		dstWb;
	short		dstY;
	short		dstH;
	unsigned short	ptBank;
	unsigned short	ptOffAddr;
} ASLQuadrangleParameter;


#if !defined( _ASLLIB_ )
void ASLMakeZoomSprite( ASLSource *src, short dstX, short dstY, short scale,
	ASLSct *sct );
void ASLMakeRotateSprite( ASLSource *src, short dstX, short dstY, short theta,
	ASLSct *sct );
void ASLMakeZoomRotateSprite( ASLSource *src, short dstX, short dstY,
	short theta, short scale, ASLSct *sct );
void ASLMakeQuadrangleSprite( ASLSource *src, ASLQuadrangleParameter *param,
	ASLPt pt[], ASLSct *sct );

void ASLSetSpriteTable( int bank, int sctNo, int num, ASLSct *sct );
void ASLSetParameterTable( int ptBank, int ptOffAddr, int num, ASLPt *pt );

#if !defined( ASL_USE_MACRO )
void ASLMakeSimpleSprite( ASLSource *src, short dstX, short dstY,ASLSct *sct );
void ASLMakeSpriteWithZ( ASLSource *src, short dstX, short dstY,
	unsigned short zval, Bool zcmp, Bool zwen, ASLSct *sct );
void ASLChangeHVFlip( ASLSct *sct, Bool flipH, Bool flipV );
void ASLChangeZ( ASLSct *sct, Bool zcmp, Bool zwen, unsigned short zval );
void ASLChangeCollisionDetection( ASLSct *sct, Bool enable, int index,
	unsigned short set_bits, unsigned short check_mask );
void ASLClearCollisionDetectionResult( int index, unsigned short value );
unsigned short ASLSenseCollisionDetectionResult( int index );
void ASLSetSpriteWindow( unsigned short left, unsigned short top,
	unsigned short right, unsigned short bottom );
void ASLExecuteSprite( int bank, int sctNo, int num );
void ASLSync( void );
void ASLWaitForSwap( void );
#endif	/* ASL_USE_MACRO */
#endif	/* _ASLLIB_ */

#if defined( ASL_USE_MACRO )
#define	ASLMakeSimpleSprite(src,dstX,dstY,sct) {			\
	(sct)->head	   = ASL_VAL_FNC_NORM				\
				| ( (src)->bank & ASL_MSK_BANKSEL );	\
	(sct)->cntl	   = 0;						\
	(sct)->dsp_x_pos   = ( (dstX) - (src)->x_hot ) & ASL_MSK_DSP_X_POS; \
	(sct)->dsp_y_pos   = ( (dstY) - (src)->y_hot ) & ASL_MSK_DSP_Y_POS; \
	(sct)->dsp_xy_size =						\
		  ( ( ( (src)->x_size - 1 ) << ASL_SFT_DSP_X_SIZE )	\
						& ASL_MSK_DSP_X_SIZE )	\
		| ( ( ( (src)->y_size - 1 ) << ASL_SFT_DSP_Y_SIZE )	\
						& ASL_MSK_DSP_Y_SIZE );	\
	(sct)->src_xy_pos  =						\
		  ( (  (src)->x_pos << ASL_SFT_SRC_X_POS )		\
						& ASL_MSK_SRC_X_POS )	\
		| ( (  (src)->y_pos << ASL_SFT_SRC_Y_POS )		\
						& ASL_MSK_SRC_Y_POS );	\
}

#define	ASLMakeSpriteWithZ(src,dstX,dstY,zval,zcmp,zwen,sct) {		\
	(sct)->head        = ASL_VAL_FNC_NORM_Z				\
				| ( (src)->bank & ASL_MSK_BANKSEL );	\
	(sct)->cntl        = ( (zcmp) ? ASL_VAL_ZCMP : 0 )		\
			   | ( (zwen) ? ASL_VAL_ZWEN : 0 );		\
	(sct)->dsp_x_pos   = ( (dstX) - (src)->x_hot ) & ASL_MSK_DSP_X_POS; \
	(sct)->dsp_y_pos   = ( (dstY) - (src)->y_hot ) & ASL_MSK_DSP_Y_POS; \
	(sct)->dsp_xy_size =						\
		  ( ( ( (src)->x_size - 1 ) << ASL_SFT_DSP_X_SIZE )	\
						& ASL_MSK_DSP_X_SIZE )	\
		| ( ( ( (src)->y_size - 1 ) << ASL_SFT_DSP_Y_SIZE )	\
						& ASL_MSK_DSP_Y_SIZE );	\
	(sct)->src_xy_pos  = ( ( (src)->x_pos << ASL_SFT_SRC_X_POS )	\
						& ASL_MSK_SRC_X_POS )	\
			   | ( ( (src)->y_pos << ASL_SFT_SRC_Y_POS )	\
						& ASL_MSK_SRC_Y_POS );	\
	(sct)->z           = (zval);					\
}

#define	ASLMakeZoomSprite(src,dstX,dstY,scale,sct) {			\
	(sct)->head	   = ASL_VAL_FNC_ZOOMROT			\
				| ( (src)->bank & ASL_MSK_BANKSEL );	\
	(sct)->cntl	   = 0;						\
	(sct)->dsp_x_pos   =						\
		( (dstX) - ( (int)( (src)->x_hot ) * (scale) ) / 256 )	\
						& ASL_MSK_DSP_X_POS;	\
	(sct)->dsp_y_pos   =						\
		( (dstY) - ( (int)( (src)->y_hot ) * (scale) ) / 256 )	\
						& ASL_MSK_DSP_Y_POS;	\
	(sct)->dsp_xy_size =						\
		  ( ( ( ( (int)(src)->x_size * (int)(scale) ) / 256 - 1 ) \
			<< ASL_SFT_DSP_X_SIZE ) & ASL_MSK_DSP_X_SIZE )	\
	 	| ( ( ( ( (int)(src)->y_size * (int)(scale) ) / 256 - 1 ) \
			<< ASL_SFT_DSP_Y_SIZE ) & ASL_MSK_DSP_Y_SIZE );	\
	(sct)->src_xy_pos  =						\
		  ( (  (src)->x_pos << ASL_SFT_SRC_X_POS )		\
						& ASL_MSK_SRC_X_POS )	\
		| ( (  (src)->y_pos << ASL_SFT_SRC_Y_POS )		\
						& ASL_MSK_SRC_Y_POS );	\
	(sct)->src_xy_size =						\
		  ( ( ( (src)->x_size - 1 ) << ASL_SFT_SRC_X_SIZE )	\
						& ASL_MSK_SRC_X_SIZE )	\
		| ( ( ( (src)->y_size - 1 ) << ASL_SFT_SRC_Y_SIZE )	\
						& ASL_MSK_SRC_Y_SIZE ); \
	(sct)->src_x_off = 0;						\
	(sct)->src_y_off = 0;						\
	(sct)->src_x_scan = 65536 / (int)(scale);			\
	(sct)->src_y_scan = 0;						\
}

#define	ASLChangeHVFlip(sct,flipH,flipV) {				\
	(sct)->head = ( (sct)->head & ~ASL_MSK_HV_FLIP )		\
					| ( (flipH) ? ASL_VAL_H_FLIP : 0 ) \
					| ( (flipV) ? ASL_VAL_V_FLIP : 0 ); \
}

#define	ASLChangeZ(sct,zcmp,zwen,zval) {				\
	(sct)->cntl = ( (sct)->cntl & ~( ASL_MSK_ZCMP | ASL_MSK_ZWEN ) ) \
					| ( (zcmp) ? ASL_VAL_ZCMP : 0 )	\
					| ( (zwen) ? ASL_VAL_ZWEN : 0 ); \
	(sct)->z    = (zval);						\
}

#define	ASLChangeCollisionDetection(sct,enable,index,set_bits,check_mask) \
{									\
	(sct)->cntl = ( (sct)->cntl & ~( ASL_MSK_CDEN | ASL_MSK_CDRES_IDX \
				| ASL_MSK_FLAG_SET | ASL_MSK_FLAG_CHK ) ) \
				| ( (enable) ? ASL_VAL_CDEN : 0 )	\
				| ( (index)	 << ASL_SFT_CDRES_IDX )	\
				| ( (set_bits)	 << ASL_SFT_FLAG_SET  )	\
				| ( (check_mask) << ASL_SFT_FLAG_CHK  ); \
}

#if defined( __ASL_DEPEND_ON_FARL )

#define	ASLClearCollisionDetectionResult(index,value) {			\
	FarlSetMemReg( FARL_CD_RESULT_REG0 + ( ( (index) >> 2 ) << 1 ), \
		FarlGetMemReg( FARL_CD_RESULT_REG0			\
					+ ( ( (index) >> 2 ) << 1 ) )	\
			& ~( 0x000f << ( ( (index) & 3 ) << 2 ) )	\
			|  ( (value)  << ( ( (index) & 3 ) << 2 ) ) );	\
}

#define	ASLSenseCollisionDetectionResult(index)				\
	( ( FarlGetMemReg( FARL_CD_RESULT_REG0				\
					+ ( ( (index) >> 2 ) << 1 ) )	\
				>> ( ( (index) & 3 ) << 2 ) ) & 0x000f )

#define	ASLSetSpriteWindow(left,top,right,bottom) {			\
	FarlSetSpWinClipReg( (left), (top), (right), (bottom) );	\
}

#define	ASLExecuteSprite(bank,sctNo,num) {				\
	FarlSpbsySpin();						\
	FarlSpriteGo( (bank), (sctNo), (num) );				\
}

#define	ASLSync() {FarlSpbsySpin();}

#else

#define	ASLClearCollisionDetectionResult(index,value) {			\
	*( (unsigned int *)FARL_CD_RESULT_REG0 ) =			\
		( *( (unsigned int *)FARL_CD_RESULT_REG0 )		\
				& ~( 0x000f << ( (index) << 2 ) )	\
				|  ( (value)  << ( (index) << 2 ) ) );	\
}

#define	ASLSetSpriteWindow(left,top,right,bottom) {			\
	*( (unsigned short *)FARL_SP_WINDOW_CLIP_XLEFT   ) = (left);	\
	*( (unsigned short *)FARL_SP_WINDOW_CLIP_YTOP    ) = (top);	\
	*( (unsigned short *)FARL_SP_WINDOW_CLIP_XRIGHT  ) = (right);	\
	*( (unsigned short *)FARL_SP_WINDOW_CLIP_YBOTTOM ) = (bottom);	\
}

#define	ASLSenseCollisionDetectionResult(index)				\
	( ( *( (unsigned int *)FARL_CD_RESULT_REG0 )			\
					>> ( (index) << 2 ) ) & 0x000f )

#define	ASLExecuteSprite(bank,sctNo,num) {				\
	while ( *( (unsigned short *)FARL_MISC_STATUS_REG )		\
					& FARL_MISC_STATUS_SBSY );	\
	*( (unsigned short *)FARL_SCT_ADDRESS_REG ) = ( (num) & 0x0700 ) \
				| ( ( (bank) & 0x001f ) << 3 )		\
				| ( ( (sctNo) & 0xff00 ) >> 8 );	\
	*( (unsigned short *)FARL_SP_CONTROL_REG )  =			\
		( ( (sctNo) & 0x00ff ) << 8 ) | ( (num) & 0xff );	\
}

#define	ASLSync() {							\
	while ( *( (unsigned short *)FARL_MISC_STATUS_REG )		\
					& FARL_MISC_STATUS_SBSY );	\
}

#endif	/* __ASL_DEPEND_ON_FARL */

#define	ASLWaitForSwap() {						\
	FarlDummySwap();						\
	FarlGetPEReg( FARL_PE_TEXTURE_REG, FARL_BLK );			\
}

#endif	/* ASL_USE_MACRO */

#define	ASLChangeCD(sct,enable,index,set_bits,check_mask)		\
	{ASLChangeCollisionDetection(sct,enable,index,set_bits,check_mask);}

#define	ASLClearCDResult(index,value)					\
		{ ASLClearCollisionDetectionResult( index, value ); }

#define	ASLSenseCDResult(index)	(ASLSenseCollisionDetectionResult(index))

#endif	/* _ASL_H_ */
